<?php
/*
 * @Date: 2020-05-03 22:03:52
 * @名称: 
 * @版本: 0.01
 * @作者: 初雪桜
 * @邮箱: 202184199@qq.com
 * @最后编辑人: 初雪桜
 * @LastEditTime: 2020-07-29 20:41:50
 * @FilePath: /Pica_acg服务器/app/serverLocalhost/common.php
 */
// 这是系统自动生成的公共文件

use think\facade\Db;
use think\facade\Session;

function generateTags($Tags)
{
    $explodeTags =  explode(',', $Tags);
    $returnInfo = "";
    foreach ($explodeTags as $key => $value) {
        $returnInfo .= "<a href='#'>$value</a>,";
    }
    $returnInfo = substr($returnInfo, 0, strlen($returnInfo) - 1);
    return $returnInfo;
}

/**
 * iSO_8601 转时间戳
 */
function iSO_8601ToNewData($data)
{
    //判断是时间戳还是时间日期格式
    $need = stripos($data, "T");
    if ($need) {
        //截取字符串转换
        $shenme = str_replace('T', ' ', $data);
        //如果是ISO8601格式,转换为时间戳
        $data = strtotime($shenme);
        $data = formatTime($data);
    }
    return $data;
}
//人性化显示时间
//$sTime int  时间戳
function formatTime($sTime, $formt = 'Y-m-d H:i:s')
{

    if (!$sTime) {
        return '';
    }

    //sTime=源时间，cTime=当前时间，dTime=时间差
    $cTime = time();
    $dTime = $cTime - $sTime;
    $dDay = intval(date('z', $cTime)) - intval(date('z', $sTime));
    $dYear = intval(date('Y', $cTime)) - intval(date('Y', $sTime));

    //n秒前，n分钟前，n小时前，日期
    if ($dTime < 60) {
        if ($dTime < 10) {
            return '刚刚';
        } else {
            return intval(floor($dTime / 10) * 10) . '秒前';
        }
    } elseif ($dTime < 3600) {
        return intval($dTime / 60) . '分钟前';
    } elseif ($dTime >= 3600 && $dDay == 0) {
        return intval($dTime / 3600) . '小时前';
    } elseif ($dDay > 0 && $dDay <= 7) {
        return intval($dDay) . '天前';
    } elseif ($dDay > 7 &&  $dDay <= 30) {
        return intval($dDay / 7) . '周前';
    } elseif ($dDay > 30) {
        return intval($dDay / 30) . '个月前';
    } elseif ($dYear == 0) {
        return date('m月d日', $sTime);
    } else {
        return date($formt, $sTime);
    }
}
/**
 * 生成分页
 *
 * @param Int $allPage //总条数
 * @param Int $page //当前页数
 * @return String
 */
function generatePaging($allPage, $page, $ExtendedParameters = "")
{
    $pageCountLimit = 20; //每一页显示多少条
    $allPage = ceil($allPage / $pageCountLimit);
    $paging = '<div class="page-wrap">
					<ul class="pagination">
                     <li class="disabled" onclick=\"locationHref(1' . $ExtendedParameters . ')\">
							<span>🏠</span>
                        </li>';
    if ($page < 3) { //判断当前页是不是3页内
        if ($allPage <= 5) { //当前页面是五页内的话 判断总页数是不是五页
            for ($i = 1; $i == $allPage; $i++) { //小于五页开始循环
                $paging .= "<li class=\"active\" onclick=\"locationHref($i$ExtendedParameters)\">
                                <span>$i</span>
                            </li>";
            }
        } else { //要是大雨三页

            if ($page == 1) { //判断当前页是不是1 是的话设置为淡蓝色
                $paging .= "<li class=\"active\" onclick=\"locationHref(1$ExtendedParameters)\">
                                <span>1</span>
                            </li>";
            } else { //否则
                $paging .= "<li onclick=\"locationHref(1$ExtendedParameters)\">
                                <span>1</span>
                            </li>";
            }
            if ($page == 2) { //判断当前页是不是2 是的话设置为淡蓝色
                $paging .= "<li class=\"active\" onclick=\"locationHref(2$ExtendedParameters)\">
                                <span>2</span>
                            </li>";
            } else { //否则
                $paging .= "<li onclick=\"locationHref(2$ExtendedParameters)\">
                                <span>2</span>
                            </li>";
            }
            if ($page == 3) { //判断当前页是不是3 是的话设置为淡蓝色
                $paging .= "<li class=\"active\" onclick=\"locationHref(3$ExtendedParameters)\">
                                <span>3</span>
                            </li>";
            } else { //否则
                $paging .= "<li onclick=\"locationHref(3$ExtendedParameters)\">
                                <span>3</span>
                            </li>";
            }
            if ($page == 4) { //判断当前页是不是4 是的话设置为淡蓝色
                $paging .= "<li class=\"active\" onclick=\"locationHref(4$ExtendedParameters)\">
                                <span>4</span>
                            </li>";
            } else { //否则
                $paging .= "<li onclick=\"locationHref(4$ExtendedParameters)\">
                                <span>4</span>
                            </li>";
            }
            if ($page == 5) { //判断当前页是不是5 是的话设置为淡蓝色
                $paging .= "<li class=\"active\" onclick=\"locationHref(5$ExtendedParameters)\">
                                <span>5</span>
                            </li>";
            } else { //否则
                $paging .= "<li onclick=\"locationHref(5$ExtendedParameters)\">
                                <span>5</span>
                            </li>";
            }
        }
    } else {
        $paging .=      "<li onclick=\"locationHref(" . ($page - 2) . "$ExtendedParameters)\">
                            <span>" . ($page - 2) . "</span>
                        </li>
                        <li onclick=\"locationHref(" . ($page - 1) . "$ExtendedParameters)\">
                            <span>" . ($page - 1) . "</span>
                        </li>
                        <li class=\"active\" onclick=\"locationHref(e)\">
                            <span>$page</span>
                        </li>";
        if ($page + 1 <= $allPage) {
            $paging .= "<li onclick=\"locationHref(" . ($page + 1) . "$ExtendedParameters )\">
                            <span>" . ($page + 1) . "</span>
                        </li>";
        }
        if ($page + 2 <= $allPage) {
            $paging .= "<li onclick=\"locationHref(" . ($page + 2) . "$ExtendedParameters)\">
                            <span>" . ($page + 2) . "</span>
                        </li>";
        }
    }

    $paging .=      "<li  onclick=\"locationHref($allPage$ExtendedParameters)\">
                            <a>end</a>
                        </li>
                    </ul>
		     </div>";
    return $paging;
}
//api请求失败返回
function errorJsonReturn($errorType = "Other-10000", $detail = false, $errorCode = 0)
{

    $lan = "lanZhCn";
    $msg = config("$lan.$errorType");
    if ($msg) {
        $return_data = json([ //超时
            "code" => $errorType,
            "msg" => config("$lan.$errorType"),
            "data" => [],
            "detail" => $detail ? $detail : ':(',
        ]);
    } else {
        $msg = config("lanZhCn.$errorType");
        if ($msg) {
            $return_data = json([ //超时
                "code" => $errorType,
                "error" => config("$lan.$errorType"),
                "data" => [],
                "detail" => $detail ? $detail : ':(',
            ]);
        } else {
            $return_data = json([
                "code" => $errorCode,
                "error" => $errorType,
                "data" => [],
                "detail" => $detail ? $detail : '未定义错误',
            ]);
        }
    }

    return $return_data;
}
//api请求成功返回
function successJsonReturn($uccessData = [], $message = "success", $uccessCode = 200)
{
    switch ($uccessCode) {
        case 200:
            $return_data = ["code" => 200, "message" => $message, "data" => $uccessData];
            break;
    }
    return json($return_data);
}/* 
function superUserVerification() //判断是不是超级用户
{
    $user_token = Session::get('super_to_ken');
    // Session::set('super_to_ken','eyJfaWQiOiI1YWYzOTNhN2RiOTFkMDJjODNkOTg3YjQiLCJlbWFpbCI6IjIwMjE4NDE5OSIsInJvbGUiOiJtZW1iZXIiLCJuYW1lIjoi6Z6g6ICA5paMIiwidmVyc2lvbiI6IjIuMi4xLjIuMy4zIiwiYnVpbGRWZXJzaW9uIjoiNDQiLCJwbGF0Zm9ybSI6ImFuZHJvaWQiLCJpYXQiOjE1ODg3ODQ2NDYsImV4cCI6MTc4OTM4OTQ0Nn0');
    if ($user_token) {
        $data = json_decode(base64_decode($user_token), true);
        //{
        //    "_id": "5af393a7db91d02c83d987b4",//id
        //    "email": "202184199",//邮箱
        //    "role": "member",
        //    "name": "鞠耀斌",
        //    "version": "2.2.1.2.3.3",
        //    "buildVersion": "44",
        //    "platform": "android",
        //    "iat": 1588784646,//申请时间
        //    "exp": 1689389446//过期时间
        //}
        if ($data["iat"] > time()) {
            $return_data = ['code' => 403, 'error' => "to_ken发生意外错误", "detail" => '重新登陆管理员账户或清空缓存'];
        } else if ($data["exp"] > time() + 604800) {
            $sever_super_user = Db::table('sever_super_user')
                ->where([
                    "to_ken" => $user_token,
                ])
                ->select();
            if (count($sever_super_user) == 1) {
                $return_data = ["code" => 200];
            } else {
                $return_data = ['code' => 401, 'error' => "遇到终极错误 请尝试重新登陆", "detail" => '重新登陆管理员账户或清空缓存'];
            }
        } else {
            $return_data = ['code' => 404, 'error' => "请重新登陆 超级用户过期", "detail" => '重新登陆管理员账户或清空缓存'];
        }
    } else {
        $return_data = ['code' => 402, 'error' => "不是管理员", "detail" => '重新登陆管理员账户或清空缓存'];
    }
    return $return_data;
} */
// /*
//  * 加密解密
//  *$str = 'abcdef';  
//  * $key = 'www.helloweba.com';  
//  * echo authcode($str,'ENCODE',$key,0); //加密  
//  * $str = '56f4yER1DI2WTzWMqsfPpS9hwyoJnFP2MpC8SOhRrxO7BOk';  
//  * echo authcode($str,'DECODE',$key,0); //解密  
//  * 
//  * @param string $string //要加密/解密的字符串
//  * @param string $operation //加密/encode 解密/decode
//  * @param string $key //密钥
//  * @param integer $expiry
//  * @return void
//  */
// function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0)
// {
//     // 动态密匙长度，相同的明文会生成不同密文就是依靠动态密匙    
//     $ckey_length = 4;

//     // 密匙    
//     $key = md5($key ? $key : config("globalsettings.serverLocalhost_Edit_EditComicsInfo_sha256Encryption"));

//     // 密匙a会参与加解密    
//     $keya = md5(substr($key, 0, 16));
//     // 密匙b会用来做数据完整性验证    
//     $keyb = md5(substr($key, 16, 16));
//     // 密匙c用于变化生成的密文    
//     $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : '';
//     // 参与运算的密匙    
//     $cryptkey = $keya . md5($keya . $keyc);
//     $key_length = strlen($cryptkey);
//     // 明文，前10位用来保存时间戳，解密时验证数据有效性，10到26位用来保存$keyb(密匙b)，  
//     //解密时会通过这个密匙验证数据完整性    
//     // 如果是解码的话，会从第$ckey_length位开始，因为密文前$ckey_length位保存 动态密匙，以保证解密正确    
//     $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) :  sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
//     $string_length = strlen($string);
//     $result = '';
//     $box = range(0, 255);
//     $rndkey = array();
//     // 产生密匙簿    
//     for ($i = 0; $i <= 255; $i++) {
//         $rndkey[$i] = ord($cryptkey[$i % $key_length]);
//     }
//     // 用固定的算法，打乱密匙簿，增加随机性，好像很复杂，实际上对并不会增加密文的强度    
//     for ($j = $i = 0; $i < 256; $i++) {
//         $j = ($j + $box[$i] + $rndkey[$i]) % 256;
//         $tmp = $box[$i];
//         $box[$i] = $box[$j];
//         $box[$j] = $tmp;
//     }
//     // 核心加解密部分    
//     for ($a = $j = $i = 0; $i < $string_length; $i++) {
//         $a = ($a + 1) % 256;
//         $j = ($j + $box[$a]) % 256;
//         $tmp = $box[$a];
//         $box[$a] = $box[$j];
//         $box[$j] = $tmp;
//         // 从密匙簿得出密匙进行异或，再转成字符    
//         $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
//     }
//     if ($operation == 'DECODE') {
//         // 验证数据有效性，请看未加密明文的格式    
//         if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) &&  substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {
//             return substr($result, 26);
//         } else {
//             return '';
//         }
//     } else {
//         // 把动态密匙保存在密文里，这也是为什么同样的明文，生产不同密文后能解密的原因    
//         // 因为加密后的密文可能是一些特殊字符，复制过程可能会丢失，所以用base64编码    
//         return $keyc . str_replace('=', '', base64_encode($result));
//     }
// }
/**
 * 生成随机id
 *
 * @param Int $randType 数据类型 
 * !0 喜欢的id
 * !1 插入作者表的id
 * !2 插入标签表的id
 * !3 categories
 * !4 书籍id
 * !5 分卷id
 * !6 分类操作id
 * @param Int $length 长度 默认22
 * @return String 数据
 */
function randIdStructure($randType, $length = 22)
{


    $stateString = null;
    switch ($randType) {
        case 0: // 喜欢id
            $stateString = "like-" . get_char(time()) . '-';
            break;
        case 1: // 插入 author_and_chinese_team_operation 的id
            $stateString = "aacto-" . get_char(time()) . '-';
            break;
        case 2: // 插入 tags 的id
            $stateString = "tags-" . get_char(time()) . '-';
            break;
        case 3: // 插入 author_and_chinese_team_operation 的id
            $stateString = "categories-" . get_char(time()) . '-';
            break;
        case 4: // 插入 author_and_chinese_team_operation 的id
            $stateString = "book-" . get_char(time()) . '-';
            break;
        case 5: // 插入 book_info_project 的id
            $stateString = "bip-" . get_char(time()) . '-';
            break;
        case 6: // 插入 log_book_info_project 的id
            $stateString = "log-bip" . get_char(time()) . '-';
            break;
        default:
            $stateString = "";
            break;
    }
    $stateString .= str_rand($length - strlen($stateString));
    return $stateString;
}
function str_rand($length, $char = '0123456789abcdefghijklmnopqrstuvwxyz')
{
    if (!is_int($length) || $length < 0) {
        return false;
    }

    $string = '';
    for ($i = $length; $i > 0; $i--) {
        $string .= $char[mt_rand(0, strlen($char) - 1)];
    }

    return $string;
}

/**
 * @desc im:十进制数转换成三十六机制数
 * @param (int)$num 十进制数
 * return 返回：三十六进制数
 */
function get_char($num)
{
    $num = intval($num);
    if ($num <= 0)
        return false;
    $charArr = array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
    $char = '';
    do {
        $key = ($num - 1) % 36;
        $char = $charArr[$key] . $char;
        $num = floor(($num - $key) / 36);
    } while ($num > 0);
    return $char;
}
/**
 * @desc im:三十六进制数转换成十机制数
 * @param (string)$char 三十六进制数
 * return 返回：十进制数
 */
function get_num($char)
{
    $array = array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z");
    $len = strlen($char);
    $sum  = 0;
    for ($i = 0; $i < $len; $i++) {
        $index = array_search($char[$i], $array);
        $sum += ($index + 1) * pow(36, $len - $i - 1);
    }
    return $sum;
}
/**
 * 查询用户权限
 *
 * @param String $UserId //用户id
 * @param String $BookId //书籍id
 * @param List $Permission //要查询的权限默认 edit_delete_user删除用户 edit_inserit_users插入用户 edit_edit_user编辑用户 edit_add_user添加用户 state状态 exp_state扩展状态
 * @return Json
 */
function PermissionQuery($UserId, $BookId, $Permission = ['edit_delete_user', 'edit_inserit_users', 'edit_edit_user', 'edit_add_user', 'state', 'exp_state'])
{
    array_push($Permission, 'state');
    $return_data = Db::table('author_and_chinese_team')
        ->where([
            "book_id" => $BookId,
            "user_id" => $UserId,
        ])
        ->field($Permission)
        ->select();
    if (count($return_data) != 1) {
        $return_data = errorJsonReturn('The user has appeared here multiple times', '数据信息异常 请联系管理员解决');
    } else {
        if ($return_data[0]['state'] == 0) {
            $return_data = successJsonReturn($return_data[0]);
        } else {
            $return_data = errorJsonReturn('Insufficient user rights');
        }
    }
    $return_data = json_decode($return_data->getContent(), true);
    return $return_data;
}



/**
 * 用户token验证
 *
 * @param [String] $token //用户token
 * @param [Bool] $isDataBaseSelect //是否从数据库验证用户
 * @return json
     ^ array:3 [▼ 
     "code" => 200 
     "message" => "success" 
     "data" => array:1 [▼ 
       "user_info" => array:7 [▼ 
         "_id" => "user-5af393a7db91d02c83d987b4"//用户id 
         "email" => "202184199"//邮箱 
         "role" => "member" 
         "name" => "初雪桜"//昵称 如果数据库查询返回数据库的名称 
         "platform" => "web" 
         "iat" => 1595576332 
         "exp" => 1596181132 
       ] 
     ] 
   ] 
 */
function ParseUserToken($token, $isDataBaseSelect = true) //解析用户token
{

    $user_info = explode('.', $token); //用户信息
    if (count($user_info) != 3) { //# token 为三段设计 第一段生成方式 没有任何意义 第二段 加密的数据  第三段 验证
        return json_decode(errorJsonReturn("Token-10000")->getContent(), true);
    }

    $user_token = base64_decode($user_info[1]);
    $Verification = $user_info[2];
    $user_info = json_decode(authcode($user_token, "DECODE", config('serverConfig.TokenResolutionKey')), true);
    if (!$user_info) { //token 解析失败
        return json_decode(errorJsonReturn("Token-10001")->getContent(), true);
    }
    if ($user_info["exp"] < time()) { //判断是否超时
        return json_decode(errorJsonReturn("Other-10000")->getContent(), true);
    }
    if ($Verification != hash_hmac("sha512", base64_encode($user_token), config('serverConfig.TokenResolutionKeySha512'))) { //验证token是否正确
        return json_decode(errorJsonReturn("Token-10002")->getContent(), true);
    }
    if ($isDataBaseSelect) { //从数据库查询用户信息
        $user_start = Db::table('admin_user_info')
            ->where([
                "_id" => $user_info['_id'],
                "user_name" => $user_info["email"],
                "to_ken" => $token,
            ])
            ->select();
        if (count($user_start) > 1) {
            return json_decode(errorJsonReturn("User-10000")->getContent(), true);
        }
        if (count($user_start) < 1) {
            return json_decode(errorJsonReturn("User-10001")->getContent(), true);
        }
    }
    return json_decode(successJsonReturn(['user_info' => $user_info])->getContent(), true);
}

/**
 * 验证用户token 返回用户信息
 * 获取token 解密出自己 token 被hmac后的结果 然后 获取cookie里面的token 进行加密 对比结果 如果出错 返回出错信息
 * @param String $token 用户加密token
 * @param String $key1 //用户加密密钥1 用 hmac加密的 不可解密
 * @param String $key2 //用户加密密钥2 用 authcode 加密的密钥
 * @return void 用户token
 */
function VerificationToken($token, $encodeData, $key1,  $key2)
{
    $ParseHashHmac_toKen = json_decode(authcode($token, 'DECODE', $key2), true);
    #!解密传入的用户信息,
    /* $ParseHashHmac_toKen = {
        "time": //加密的时间戳
        "hashHmac_token"://验证字符串
        } */
    //判断有没有解析成功
    if ($ParseHashHmac_toKen == null) {
        return json_decode(errorJsonReturn("Token-10001")->getContent(), true);
        #用户token验证失败 提交的token 和验证的token不一个
    }
    //验证有没有超时
    if ($ParseHashHmac_toKen['time'] < time()) {
        return json_decode(errorJsonReturn("Other-10000")->getContent(), true);
        #用户token验证失败 提交的token 和验证的token不一个
    }

    $hash_hmac = hash_hmac('sha256', $encodeData . $ParseHashHmac_toKen['time'], $key1);

    if ($ParseHashHmac_toKen['hashHmac_token'] != $hash_hmac) {
        return json_decode(errorJsonReturn("Token-10002")->getContent(), true);
    } else {
        return json_decode(successJsonReturn()->getContent(), true);
    }
}


function EncryptedData($encodeData, $timeOut, $key1, $key2)
{
    $time =  time() + $timeOut;
    $hashHmac_toKen = [
        "time" => $time, //超时六十分钟过期
        "hashHmac_token" => hash_hmac('sha256', $encodeData . $time, $key1),
    ];
    return authcode(json_encode($hashHmac_toKen), 'encode', $key2);
}

//查询用户权限 仅限于网站后台查询

function selectSuperUserJurisdiction($user_id, $Permission = ['images_update', 'edit_class_info',])
{
    array_push($Permission, 'state');
    $user_info =  Db::table('admin_user_info')
        ->where([
            "_id" => $user_id,
        ])
        ->field($Permission)
        ->find();
    if ($user_info) {
        return json_decode(successJsonReturn($user_info)->getContent(), true);
    } else {
        return json_decode(errorJsonReturn("User-10002")->getContent(), true);
    }
}
